/**
 * @file    pace_modbus.c
 * @brief   沛城逆变器协议-V1.3
 * @author  Liuwei
 * @version 1.0.1
 * @date    2024-04-29
 * PACE Modbus-bms-protocol V1.3.pdf
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2024-04-29 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "pace_modbus.h"
#include "modbus_app.h"
#include "if_di.h"
#include "cfg_prj.h"
#include "sample.h"
#include "parallel_com.h"
#include "var_mng.h"
#include "param_mng.h"
#include "OZ7717.h"
/* macro/define --------------------------------------------------------------*/

/* typedef -------------------------------------------------------------------*/
#define INTPUT_REG_SIZE      (180)
#define CMD_READ_IN_REG      (0x03)
/* local functions -----------------------------------------------------------*/
static void pace_read_input_reg(md_data_type md_data_msg , uint8_t *tx_buf ,uint16_t *tx_len);
static void pace_update_input_buf(void);
static uint16_t get_alarm_msg(void);
static uint16_t get_prp_state(void);
static uint16_t get_fault_state(void);
/* static variables ----------------------------------------------------------*/
static uint16_t input_reg_buf[INTPUT_REG_SIZE] = {0};

/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
uint8_t pace_modbus_analysis(uint8_t *rx_buf , uint16_t rx_len ,uint8_t *tx_buf , uint16_t *tx_len)
{
    md_data_type recv_md_data = {0};
    if(TRUE == modbus_rtu_analysis(rx_buf , rx_len , &recv_md_data))
    {
        if(1 == recv_md_data.addr)
        {
            if((recv_md_data.reg_addr + recv_md_data.data_len <= INTPUT_REG_SIZE)
              &&(CMD_READ_IN_REG == recv_md_data.cmd_code))
            {
                pace_update_input_buf();
                pace_read_input_reg(recv_md_data , tx_buf , tx_len);
                return TRUE;
            }
            return FALSE;
        }
        return FALSE;
    }
    return FALSE;
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
static void pace_read_input_reg(md_data_type md_data_msg, uint8_t *tx_buf, uint16_t *tx_len) 
{
    uint16_t data_len = 0;
    uint16_t crc_code = 0;
    uint8_t i = 0;
    uint8_t *p_tx = tx_buf;

    *p_tx ++ = md_data_msg.addr;
    *p_tx ++ = md_data_msg.cmd_code;
    data_len = md_data_msg.data_len * 2; 
    *p_tx ++ = data_len; 
   	
    for(i = 0;i < md_data_msg.data_len; ++ i)
    {
		
        *p_tx ++ = input_reg_buf[i + md_data_msg.reg_addr] >> 8;
        *p_tx ++  = input_reg_buf[i + md_data_msg.reg_addr] & 0xff;
    }
	
    crc_code = modbus_calc_crc(tx_buf , data_len + 3);

    *p_tx ++ = crc_code;
    *p_tx ++ = crc_code >> 8;

    *tx_len = (data_len + 5);
}

static void pace_update_input_buf(void)
{
    int16_t sys_curr = 0;
    uint8_t i = 0;

    sys_curr = master_data_reg.total_bus_curr;
    input_reg_buf[0x00] = sys_curr;
    input_reg_buf[0x01] = master_data_reg.avg_batt_volt;
    input_reg_buf[0x02] = master_data_reg.avg_soc;
	input_reg_buf[0x03] = master_data_reg.avg_soh;
	input_reg_buf[0x04] = master_data_reg.total_real_cap ;
    input_reg_buf[0x05] = master_data_reg.total_full_cap ;
    input_reg_buf[0x06] = master_data_reg.total_std_cap ;
    input_reg_buf[0x07] = master_data_reg.avg_cycle;
	input_reg_buf[0x08] = 0;
    input_reg_buf[0x09] = get_alarm_msg();
	input_reg_buf[0x0A] = get_prp_state();
	input_reg_buf[0x0B] = get_fault_state();
	input_reg_buf[0x0C] = var_get_data(VAR_ID_BLC_NOW_IDX);
	input_reg_buf[0x0D] = 0;
	input_reg_buf[0x0E] = 0;
	
	for(i = 0;i < 16; ++ i)
	{
		input_reg_buf[15 + i] = var_get_data(VAR_ID_CELL_VOLT01 + i);
	}
	for(i = 0;i < 4; ++ i)
	{
		input_reg_buf[31 + i] = var_get_data(VAR_ID_CELL_TEMP01 + i)- 500;
	}
	input_reg_buf[35] = var_get_data(VAR_ID_TP_AVG_MOST) - 2731;
	input_reg_buf[36] = var_get_data(VAR_ID_TP_AVG_ENVT) - 2731;
	input_reg_buf[37] = var_get_data(VAR_ID_TP_SOP_CV);
	input_reg_buf[38] = var_get_data(VAR_ID_TP_SOP_CC);
	input_reg_buf[39] = var_get_data(VAR_ID_TP_SOP_DV);
	input_reg_buf[40] = var_get_data(VAR_ID_TP_SOP_DC);
	
	input_reg_buf[60] = param_get_data(PAR_ID_BOV_ALM_VAL)*10;
    input_reg_buf[61] = param_get_data(PAR_ID_BOV_PRP_VAL)*10;
    input_reg_buf[62] = param_get_data(PAR_ID_BOV_PRP_RCV)*10;
    input_reg_buf[63] = param_get_data(PAR_ID_BOV_PRP_DLY)*0.01;
    input_reg_buf[64] = param_get_data(PAR_ID_COV_ALM_VAL);
    input_reg_buf[65] = param_get_data(PAR_ID_COV_PRP_VAL);
    input_reg_buf[66] = param_get_data(PAR_ID_COV_PRP_RCV);
    input_reg_buf[67] = param_get_data(PAR_ID_COV_PRP_DLY)*0.01;
    input_reg_buf[68] = param_get_data(PAR_ID_BUV_ALM_VAL)*10;
    input_reg_buf[69] = param_get_data(PAR_ID_BUV_PRP_VAL)*10;
    input_reg_buf[70] = param_get_data(PAR_ID_BUV_PRP_RCV)*10;
    input_reg_buf[71] = param_get_data(PAR_ID_BUV_PRP_DLY)*0.01;
    input_reg_buf[72] = param_get_data(PAR_ID_CUV_ALM_VAL);
    input_reg_buf[73] = param_get_data(PAR_ID_CUV_PRP_VAL);
    input_reg_buf[74] = param_get_data(PAR_ID_CUV_PRP_RCV);
    input_reg_buf[75] = param_get_data(PAR_ID_CUV_PRP_DLY) * 0.01;
    input_reg_buf[76] = param_get_data(PAR_ID_OCC_ALM_VAL) * 0.1;
    input_reg_buf[77] = param_get_data(PAR_ID_OCC_PRP_VAL) * 0.1;
    input_reg_buf[78] = param_get_data(PAR_ID_OCC_PRP_DLY) * 0.01;
    input_reg_buf[79] = param_get_data(PAR_ID_OCD1_ALM_VAL) * 0.1;
    input_reg_buf[80] = param_get_data(PAR_ID_OCD1_PRP_VAL) * 0.1;
    input_reg_buf[81] = param_get_data(PAR_ID_OCD1_PRP_DLY) * 0.01;
    input_reg_buf[82] = param_get_data(PAR_ID_OCD2_PRP_VAL) * 0.1;
    input_reg_buf[83] = param_get_data(PAR_ID_OCD2_PRP_DLY) / 25;
    input_reg_buf[84] = param_get_data(PAR_ID_OTC_ALM_VAL)-500;
    input_reg_buf[85] = param_get_data(PAR_ID_OTC_PRP_VAL)-500;
    input_reg_buf[86] = param_get_data(PAR_ID_OTC_PRP_RCV)-500;
    input_reg_buf[87] = param_get_data(PAR_ID_OTD_ALM_VAL)-500;
    input_reg_buf[88] = param_get_data(PAR_ID_OTD_PRP_VAL)-500;
    input_reg_buf[89] = param_get_data(PAR_ID_OTD_PRP_RCV)-500;
    input_reg_buf[90] = param_get_data(PAR_ID_UTC_ALM_VAL)-500;
    input_reg_buf[91] = param_get_data(PAR_ID_UTC_PRP_VAL)-500;
    input_reg_buf[92] = param_get_data(PAR_ID_UTC_PRP_RCV)-500;
    input_reg_buf[93] = param_get_data(PAR_ID_UTD_ALM_VAL)-500;
    input_reg_buf[94] = param_get_data(PAR_ID_UTD_PRP_VAL)-500;
    input_reg_buf[95] = param_get_data(PAR_ID_UTD_PRP_RCV)-500;
    input_reg_buf[96] = param_get_data(PAR_ID_OTM_ALM_VAL)-500;
    input_reg_buf[97] = param_get_data(PAR_ID_OTM_PRP_VAL)-500;
    input_reg_buf[98] = param_get_data(PAR_ID_OTM_PRP_RCV)-500;
    input_reg_buf[99] = param_get_data(PAR_ID_OTE_ALM_VAL)-500;
    input_reg_buf[100] = param_get_data(PAR_ID_OTE_PRP_VAL)-500;
    input_reg_buf[101] = param_get_data(PAR_ID_OTE_PRP_RCV)-500;
    input_reg_buf[102] = param_get_data(PAR_ID_UTE_ALM_VAL)-500;
    input_reg_buf[103] = param_get_data(PAR_ID_UTE_PRP_VAL)-500;
    input_reg_buf[104] = param_get_data(PAR_ID_UTE_PRP_RCV)-500;
    input_reg_buf[105] = param_get_data(PAR_ID_BLC_VOLT);
    input_reg_buf[106] = param_get_data(PAR_ID_BLC_VDIFF);
    input_reg_buf[107] = param_get_data(PAR_ID_FULL_CHG_VOLT)*10;
    input_reg_buf[108] = param_get_data(PAR_ID_FULL_CHG_CURR) ;
    input_reg_buf[109] = param_get_data(PAR_ID_IDE_SLP_VOLT);
    input_reg_buf[110] = param_get_data(PAR_ID_IDE_SLP_DLY);
	input_reg_buf[111] = 0;
    input_reg_buf[112] = param_get_data(PAR_ID_SOCL_ALM_VAL);
    input_reg_buf[113] = param_get_data(PAR_ID_OCC2_PRP_VAL) * 0.1;
    input_reg_buf[114] = param_get_data(PAR_ID_OCC2_PRP_DLY) / 25;
	
    input_reg_buf[150] = SOFT_VER_MAIN;
    input_reg_buf[151] = SOFT_VER_RELEASE;
	input_reg_buf[152] = SOFT_VER_TEST;
	
    for(i = 0;i < 10; ++ i)
	{
		input_reg_buf[160 + i] = param_get_data(PAR_ID_BMS_CODE + i);
	}
	
    for(i = 0;i < 10; ++ i)
	{
		input_reg_buf[170 + i] = param_get_data(PAR_ID_SN_CODE + i);
	}
}

static uint16_t get_alarm_msg(void)
{
	uint16_t alarm_msg = 0;
	
	
	return alarm_msg;
}


static uint16_t get_prp_state(void)
{
	uint16_t prp_msg = 0;
	
	if(master_data_reg.total_prp_msg.bit.occ || master_data_reg.total_prp_msg.bit.occ2)
		prp_msg |= (1 << 4);
	if(master_data_reg.total_prp_msg.bit.ocd || master_data_reg.total_prp_msg.bit.ocd2)
		prp_msg |= (1 << 5);
	if(master_data_reg.total_prp_msg.bit.sc)
		prp_msg |= (1 << 6);
	if(master_data_reg.total_prp_msg.bit.otc)
		prp_msg |= (1 << 8);
	if(master_data_reg.total_prp_msg.bit.otd)
		prp_msg |= (1 << 9);
	if(master_data_reg.total_prp_msg.bit.utc)
		prp_msg |= (1 << 10);
	if(master_data_reg.total_prp_msg.bit.utd)
		prp_msg |= (1 << 11);
	if(master_data_reg.total_prp_msg.bit.otm)
		prp_msg |= (1 << 12);
	if(master_data_reg.total_prp_msg.bit.ote)
		prp_msg |= (1 << 13);
	if(master_data_reg.total_prp_msg.bit.ute)
		prp_msg |= (1 << 14);
	
	return prp_msg;
}

static uint16_t get_fault_state(void)
{
	uint16_t ft_state = 0;
	
	if(master_data_reg.total_prp_msg.bit.fcmos)
		ft_state |= (1 << 0);
	if(master_data_reg.total_prp_msg.bit.fdmos)
		ft_state |= (1 << 1);
	if(master_data_reg.total_prp_msg.bit.tol)
		ft_state |= (1 << 2);
	if(master_data_reg.total_prp_msg.bit.col)
		ft_state |= (1 << 4);
	if(master_data_reg.total_prp_msg.bit.afe_err)
		ft_state |= (1 << 5);
	
	if(master_data_reg.total_bus_curr > 0)
		ft_state |= (1 << 8);
	else if(master_data_reg.total_bus_curr < 0)
		ft_state |= (1 << 9);
	else
	{;}
	
	if(master_data_reg.fet_status & 0x02)
		ft_state |= (1 << 10);
	if(master_data_reg.fet_status & 0x01)
		ft_state |= (1 << 11);
	
	return ft_state;
}
/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
